package com.feng.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feng.Exception.SystemException;
import com.feng.constants.SystemConstants;
import com.feng.domain.ResponseResult;
import com.feng.domain.dto.UserSaveDto;
import com.feng.domain.entity.Role;
import com.feng.domain.entity.User;
import com.feng.domain.entity.UserRole;
import com.feng.domain.enums.AppHttpCodeEnum;
import com.feng.domain.vo.*;
import com.feng.mapper.MenuMapper;
import com.feng.mapper.RoleMapper;
import com.feng.mapper.UserMapper;
import com.feng.service.UserRoleService;
import com.feng.service.UserService;
import com.feng.util.BeanCopyUtils;
import com.feng.util.RedisCache;
import com.feng.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户表(User)表服务实现类
 *
 * @author makejava
 * @since 2022-10-11 23:04:11
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
 @Autowired
 private UserMapper userMapper;
 @Autowired
 private PasswordEncoder passwordEncoder;
 @Autowired
 private UserRoleService userRoleService;
 @Autowired
 private UserService userService;
 @Autowired
 private MenuMapper menuMapper;
 @Autowired
 private RoleMapper roleMapper;
 @Autowired
 private RedisCache redisCache;
 @Autowired
 private RedisTemplate<String,String> redisTemplate;
    @Override
    public ResponseResult userInfo() {
        //获取当前用户id
        Long userId = SecurityUtils.getUserId();
        //根据用户id进行查询
        User user = userMapper.selectById(userId);
        //封装成userInfo进行返回
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(user, UserInfoVo.class);
        return ResponseResult.okResult(userInfoVo);
    }

    @Override
    public ResponseResult  updateUserInfo(User user) {
        //获取当前用户id
        Long userId = SecurityUtils.getUserId();
        if(userId==null){
            return ResponseResult.errorResult(401,"请重新登录!");
        }
        LambdaQueryWrapper<User> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail,user.getEmail());
        User user1 = userMapper.selectOne(queryWrapper);
        user.setId(user1.getId());
        this.updateById(user);

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult register(User user) {
        //对数据进行非空判断
       if(!StringUtils.hasText(user.getUserName())){
           throw new SystemException(AppHttpCodeEnum.USERNAME_NOT_NULL);
       }
        if(!StringUtils.hasText(user.getPassword())){
            throw new SystemException(AppHttpCodeEnum.PASSWORD_NOT_NULL);
        }
        if(!StringUtils.hasText(user.getNickName())){
            throw new SystemException(AppHttpCodeEnum.NICKNAME_NOT_NULL);
        }
        if(!StringUtils.hasText(user.getEmail())){
            //验证码不能为空
            throw new SystemException(AppHttpCodeEnum.PHONE_NOT_NULL);
        }
        //对数据进行是否存在的判断
        LambdaQueryWrapper<User> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName,user.getUserName());
        User user1 = userMapper.selectOne(queryWrapper);
        if(!ObjectUtils.isEmpty(user1)){
            //用户名已存在
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
        LambdaQueryWrapper<User> userLambdaQueryWrapper=new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getEmail,user.getEmail());
        User user2 = userMapper.selectOne(userLambdaQueryWrapper);
        if(!ObjectUtils.isEmpty(user2)){
            //手机已存在
            throw new SystemException(AppHttpCodeEnum.PHONENUMBER_EXIST);
        }
        //判断验证码和存的验证码是否一样
        String email = user.getEmail();
        String code = (String) redisTemplate.opsForValue().get(email);
        //验证码已过期
        if(!StringUtils.hasText(code)){
            throw new SystemException(AppHttpCodeEnum.CODE_EXPIRE);
        }
        //验证码错误
        if(!code.equals(user.getCode())){
            throw new SystemException(AppHttpCodeEnum.CODE_ERROR);
        }


        //密码进行加密
        String encode = passwordEncoder.encode(user.getPassword());
        user.setPassword(encode);
        user.setAvatar("https://fgblog.oss-cn-guangzhou.aliyuncs.com/2023/04/04/21d0b4e602b54717a60067f539d6d5f8D5DCF17BA51FAA5441E52179AFA6BF31.png");
        //存入数据库
        this.save(user);
        //返回封装类型
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult selectUserPage(User user, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper();
         //条件查询
        //可以根据用户名模糊搜索。
        //​	可以进行手机号模糊搜索。
        //​	可以进行状态的查询。
        queryWrapper.like(StringUtils.hasText(user.getUserName()),User::getUserName,user.getUserName());
        queryWrapper.eq(StringUtils.hasText(user.getStatus()),User::getStatus,user.getStatus());
        queryWrapper.like(StringUtils.hasText(user.getPhonenumber()),User::getPhonenumber,user.getPhonenumber());

        Page<User> page = new Page<>();
        page.setCurrent(pageNum);
        page.setSize(pageSize);
        page(page,queryWrapper);

        //转换成VO
        List<User> users = page.getRecords();
        List<UserVo> userVos = BeanCopyUtils.copyBeanList(users, UserVo.class);
        PageVo pageVo=new PageVo(userVos,page.getTotal());

        return ResponseResult.okResult(pageVo);
    }

    @Override
    public boolean checkUserNameUnique(String userName) {
        LambdaQueryWrapper<User> queryWrapper=new LambdaQueryWrapper<>();
        //查询是否有同名的用户
        queryWrapper.eq(User::getUserName,userName);
        List<User> list = this.list(queryWrapper);
        if(list.size()==0){
            return true;
        }
       else{
           return false;
        }
    }

    @Override
    public boolean checkPhoneUnique(String phonenumber) {
        LambdaQueryWrapper<User> queryWrapper=new LambdaQueryWrapper<>();
        //查询手机号是否存在
        queryWrapper.eq(User::getPhonenumber,phonenumber);
        List<User> list = this.list(queryWrapper);
        if(list.size()==0){
            return true;
        }
        else{
            return false;
        }
    }

    @Override
    public boolean checkEmailUnique(String email) {
        LambdaQueryWrapper<User> queryWrapper=new LambdaQueryWrapper<>();
        //查询邮箱是否已经存在
        queryWrapper.eq(User::getEmail,email);
        List<User> list = this.list(queryWrapper);
        if(list.size()==0){
            return true;
        }
        else{
            return false;
        }
    }

    @Override
    public ResponseResult addUser(UserSaveDto userSaveDto) {
        //密码需要加密后在存入数据库
        User user = BeanCopyUtils.copyBean(userSaveDto, User.class);
        user.setPassword(passwordEncoder.encode(userSaveDto.getPassword()));
         //保存用户表
        save(user);
        if(userSaveDto.getRoleIds()!=null&&userSaveDto.getRoleIds().size()>0){
            List<Long> roleIds = userSaveDto.getRoleIds();
            //获得当前用户的id
            Long id = user.getId();
            for (Long roleId : roleIds) {
                UserRole userRole=new UserRole();
                userRole.setRoleId(roleId);
                userRole.setUserId(id);
                //将userRole插入表中
                userRoleService.save(userRole);
            }
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getDetailByUserId(Long id) {
        User user = userService.getById(id);
        //拷贝对象
        UserUpdateVo userUpdateVo = BeanCopyUtils.copyBean(user, UserUpdateVo.class);
       //查询状态正常的role信息
        LambdaQueryWrapper<Role> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getStatus, SystemConstants.STATUS_NORMAL);
        List<Role> roles = roleMapper.selectList(queryWrapper);

        List<RoleVo> roleVos = BeanCopyUtils.copyBeanList(roles, RoleVo.class);
        //查询该用户具有的权限id
        List<Long> list = roleMapper.selectRoleIdByUserId(id);
       //封装vo对象进行返回
       UserInfoAndRoleIdsVo userInfoAndRoleIdsVo=new UserInfoAndRoleIdsVo(userUpdateVo,roleVos,list);

       return ResponseResult.okResult(userInfoAndRoleIdsVo);


    }

    @Override
    public ResponseResult updateUser(UserUpdateVo userUpdateVo) {
        //拷贝对象
        User user = BeanCopyUtils.copyBean(userUpdateVo, User.class);
        updateById(user);
        //获得用户的id
        Long id = userUpdateVo.getId();
        //先将用户关联的role信息删除
        LambdaQueryWrapper<UserRole> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getUserId,id);
        userRoleService.remove(queryWrapper);
        List<Long> roleIds = userUpdateVo.getRoleIds();
        for (Long roleId : roleIds) {
            //将其进行保存
            UserRole userRole=new UserRole();
            userRole.setUserId(id);
            userRole.setRoleId(roleId);
            userRoleService.save(userRole);
        }
        //返回
        return ResponseResult.okResult();

    }

    @Override
    public ResponseResult updatePas(User user) {
        //获取前端传来的密码
        String password = user.getPassword();
        if(!StringUtils.hasText(password)){
            //密码不能为空
            throw new SystemException(AppHttpCodeEnum.PASSWORD_NOT_NULL);
        }
        //获取当前登录用户的id
        Long userId = SecurityUtils.getUserId();
        if(userId==null){
            //获取不到userId证明已经过期，其实在拦截器已经判断，再加一层以免出现bug
            throw new SystemException(AppHttpCodeEnum.USER_EXPIRES);
        }

        LambdaQueryWrapper<User> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId,userId);
        //得到当前的用户
        User one = this.getOne(queryWrapper);
        String newPassword = passwordEncoder.encode(password);
        //更新条件
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User :: getId, one.getId());
        updateWrapper.set(User :: getPassword,newPassword);

        userService.update(updateWrapper);
        redisCache.deleteObject("bloglogin:"+userId);
        return ResponseResult.okResult("密码修改成功！");

    }


}

